package com.rdtravel.web;

import com.rdtravel.entities.Trip;
import com.rdtravel.services.DestinationsService;
import com.rdtravel.services.TripsService;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Locale;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.servlet.ModelAndView;

@Controller
@RequestMapping("/destinations")
class DestinationsController {
	private static final String VIEW = "destinations/destinations";
	private final DestinationsService destinationsService;
	private final TripsService tripsService;

	@Autowired
	public DestinationsController(DestinationsService destinationsService,
			TripsService tripsService) {
		this.destinationsService = destinationsService;
		this.tripsService = tripsService;
	}

	private void setLanguageAndDatePattern(ModelAndView modelAndView,
			Locale locale) {
		DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.SHORT,
				locale);
		SimpleDateFormat simpleDateFormat = (SimpleDateFormat) dateFormat;
		String pattern = simpleDateFormat.toPattern();
		pattern = pattern.replace('M', 'm');
		modelAndView.addObject("pattern", pattern);
		modelAndView.addObject("language", locale.getLanguage());
	}

	@RequestMapping(method = RequestMethod.GET)
	public ModelAndView findDestinationByNameForm(Locale locale,
			@RequestParam(required = false) String destination) {
		ModelAndView modelAndView = new ModelAndView(VIEW);
		setLanguageAndDatePattern(modelAndView, locale);
		TripsSearchForm tripsSearchForm = new TripsSearchForm();
		if (destination != null) {
			tripsSearchForm.setDestination(destinationsService
					.findByName(destination));
		}
		modelAndView.addObject(tripsSearchForm);
		return modelAndView;
	}

	@RequestMapping(method = RequestMethod.GET, params = "searchTrips")
	public ModelAndView findDestinationByName(
			@Valid TripsSearchForm tripsSearchForm,
			BindingResult bindingResult, Locale locale) {
		ModelAndView modelAndView = new ModelAndView(VIEW);
		if (!bindingResult.hasErrors()) {
			List<Trip> trips = tripsService
					.findByDestinationAndDepartureLocationAndPeriod(
							tripsSearchForm.getDestination(),
							tripsSearchForm.getDepartureLocation(),
							tripsSearchForm.getPeriod(),
							tripsSearchForm.getSeats());
			modelAndView.addObject("trips", trips);
			if (trips.isEmpty()) {
				modelAndView.addObject("noTripsFound", true);
			}
		}
		setLanguageAndDatePattern(modelAndView, locale);
		return modelAndView;
	}

	@RequestMapping(value = "names", method = RequestMethod.GET, params = "term", produces = MediaType.APPLICATION_JSON_VALUE)
	public @ResponseBody
	List<String> findNamesStartingWith(@RequestParam String term) {
		return destinationsService.findNamesStartingWith(term);
	}

	@ExceptionHandler(IllegalArgumentException.class)
	@ResponseStatus(HttpStatus.BAD_REQUEST)
	public @ResponseBody
	String illegalArgumentHandler(IllegalArgumentException ex) {
		return ex.getMessage();
	}
}
